home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / UTIL / MEMORY / VIRTUASRC / !Virtual / s / virtual < prev   
Text File  |  1993-09-07  |  22KB  |  703 lines

  1. ; virtual.s
  2. ; Part of the !Virtual distribution
  3. ; (c) bdb/nas/fo, 1992-3
  4.  
  5. ; Assemble with:
  6. ;aasm s.Virtual Virtual -M -Q
  7.  
  8.         GBLL    DEBUG
  9. DEBUG   SETL    {FALSE}
  10.         GBLL     SWIS
  11. SWIS    SETL    {TRUE}
  12.  
  13.         GBLL    OLD_VERSION
  14. OLD_VERSION     SETL    {FALSE}
  15.  
  16. R0      RN      0
  17. R1      RN      1
  18. R2      RN      2
  19. R3      RN      3
  20. R4      RN      4
  21. R5      RN      5
  22. R6      RN      6
  23. R7      RN      7
  24. R8      RN      8
  25. R9      RN      9
  26. SL      RN      10
  27. FP      RN      11
  28. IP      RN      12
  29. SP      RN      13
  30. LR      RN      14
  31. PC      RN      15
  32. a1      RN      0
  33. a2      RN      1
  34. a3      RN      2
  35. a4      RN      3
  36. v1      RN      4
  37. v2      RN      5
  38. v3      RN      6
  39. v4      RN      7
  40. v5      RN      8
  41. v6      RN      9
  42. fp      RN      10
  43. ip      RN      11
  44. sp      RN      12
  45. lr      RN      14
  46. pc      RN      15
  47.  
  48. N_bit           *       1 :SHL: 31
  49. Z_bit           *       1 :SHL: 30
  50. C_bit           *       1 :SHL: 29
  51. V_bit           *       1 :SHL: 28
  52. I_bit           *       1 :SHL: 27
  53. F_bit           *       1 :SHL: 26
  54.  
  55. USR_mode        *      0
  56. FIQ_mode        *      1
  57. IRQ_mode        *      2
  58. SVC_mode        *      3
  59.  
  60.         GET     Hdr.Swis
  61.         GET     Hdr.Module
  62.  
  63.         SUBT    S.Virtual - virtual memory thing.
  64.  
  65. swibase *       &47900          ; Acorn-allocated :-)
  66.  
  67.         MACRO
  68.         CLRV    $cc
  69.         CMP$cc  pc,#0
  70.         MEND
  71.  
  72.         MACRO
  73.         NOP
  74.         ANDEQ   R0,R0,R0
  75.         MEND
  76.  
  77. ; per task workspace
  78.  
  79.                 ^       0,ip
  80. regs            #       64
  81. stacktop        #       4
  82.  
  83.                 AREA    |!!!Module$$Header|,CODE,READONLY
  84.  
  85. base            &       start-base
  86.                 &       init-base
  87.                 &       finish-base
  88.                 &       service-base
  89.                 &       title-base
  90.                 &       help-base
  91.                 &       cmdtab-base
  92.                 [       SWIS
  93.                 &       swibase
  94.                 &       swihandler-base
  95.                 &       switable-base
  96.                 &       0
  97.                 ]
  98.  
  99. title           =       "Virtual",0
  100. help            =       "Virtual Memory",9,"0.37 (07 Sep 1993) by BDB/NAS/FO",0
  101.  
  102. cmdtab          =       "Virtual",0
  103.                 ALIGN
  104.                 &       Virtual-base
  105.                 =       0,0,20,0
  106.                 &       Virtualsynx-base
  107.                 &       Virtualhelp-base
  108.                 &       0
  109.  
  110. Virtualhelp     =       "The *Virtual command allows a task to be run with virtual memory.",13,10
  111.  
  112. Virtualsynx     =       "Syntax: *Virtual [<command>] [-wimpslot <n>K] [-discslot <n>M] [-name <taskname>] [-nice <n>] [-ctrl] [-display] [-quit]",13,10
  113.                 =       "  <command> is the command to be executed",13,10
  114.                 =       "  -wimpslot sets the physical memory to be allocated; the virtual memory is set by the -discslot parameter, default 24M",13,10
  115.                 =       "  -nice sets the task priority: 9 low priority, 0 high priority, default 4",13,10
  116.                 =       "  -name sets the task name",13,10
  117.                 =       "  -ctrl allows control characters through",13,10
  118.                 =       "  -display opens the task window immediately, rather than waiting for a character to be printed",13,10
  119.                 =       "  -quit makes the task quit after the command even if the task window has been opened",13,10
  120.                 =       "Note that fields must be in "" "" if they comprise more than one word", 0
  121.  
  122.                 [       SWIS
  123.                 ALIGN
  124. switable        =       "Virtual",0
  125.                 =       "TaskInfo",0
  126.                 =       "Physical",0
  127.                 =       0
  128.                 ]
  129.  
  130. ;SL env WriteS
  131. ;FP instantiation number
  132. ;IP currently preferred instantiation
  133. ;SP SVC mode  stack
  134. ;Preserve R7-FP,SP
  135.  
  136.                 IMPORT  |__RelocCode|
  137.                 IMPORT  Cinit
  138.  
  139. init            STMDB   SP!,{SL,FP,LR}
  140.                 BL      |__RelocCode|
  141.                 MOV     a1,IP
  142.                 MOV     sp,SP
  143.                 SUB     SP,SP,#1024
  144.                 MOV     fp,#0
  145.                 BL      Cinit
  146.                 CLRV
  147.                 TEQ     R0,#0
  148.                 TEQNEP  PC,#V_bit+SVC_mode
  149.                 ADD     SP,SP,#1024
  150.                 LDMIA   SP!,{SL,FP,PC}
  151.  
  152. ;R1 service number, may zero
  153. ;IP currently preferred instantiation
  154. ;SP a stack, SVC or IRQ
  155. ;Preserve R0,R2-R8 unless returning values
  156. ;May corrupt IP
  157.  
  158. service         TEQ     R1,#&11         ;Service_Memory
  159.                 MOVNE   PC,LR
  160.                 ADR     IP,base
  161.                 TEQ     R2,IP
  162.                 MOVEQ   R1,#0           ;claim
  163.                 MOV     PC,LR
  164.  
  165. ;R0 command tail
  166. ;R1 command count
  167. ;IP currently preferred instantiation
  168. ;SP SVC mode stack
  169. ;Preserve R7-FP
  170.  
  171. Virtual         STMFD   SP!,{LR}
  172.                 LDR     IP,[IP]
  173.                 MOV     R2,R0   ;parameters
  174.                 MOV     R0,#2   ;Enter
  175.                 ADR     R1,title
  176.                 SWI     XOS_Module
  177.                 LDMFD   SP!,{PC}
  178.  
  179. ;SL fatal flag
  180. ;FP instantiation number
  181. ;IP currently preferred instantiation
  182. ;SP SVC mode stack
  183. ;Preserve R7-FP,SP
  184.  
  185.                 IMPORT  Cfinish
  186.  
  187. finish          STMDB   SP!,{SL,FP,LR}
  188.                 MOV     a1,IP
  189.                 MOV     sp,SP
  190.                 SUB     SP,SP,#1024
  191.                 MOV     fp,#0
  192.                 BL      Cfinish
  193.                 CLRV
  194.                 TEQ     R0,#0
  195.                 TEQNEP  PC,#V_bit+SVC_mode
  196.                 ADD     SP,SP,#1024
  197.                 LDMIA   SP!,{SL,FP,PC}
  198.  
  199.                 [       SWIS
  200. ;(R9 SWI chunk *4)
  201. ;(SL routine addr)
  202. ;FP SWI number mod 64
  203. ;IP private word
  204. ;SP super stack (R9 LR swi-no SL FP IP)
  205. ;LR flags of caller with VC
  206. ;(R9,)SL-IP may be corrupted, return with MOVS
  207. ;R0-R8 as caller
  208. ;IRQs (NOT) disabled on entry, may enable them
  209.  
  210. swihandler      LDR     IP,[IP]
  211.                 STMFD   SP!,{R0-R3,LR}
  212.                 CMP     FP,#(endjumptable-jumptable)/4
  213.                 ADDCC   PC,PC,FP,LSL#2
  214.                 B       unknownswierror
  215. jumptable       B       TaskInfo
  216.                 B       DoPhysical
  217. endjumptable
  218. unknownswierror LDMFD   SP!,{R0-R3,LR}
  219.                 ADR     R0,unknownswimsg
  220.                 ORRS    PC,LR,#V_bit
  221. unknownswimsg   &       &1E6
  222.                 =       "Unknown Virtual SWI",0
  223.                 ALIGN
  224.  
  225. ; R0 task id
  226. ; R1 Virtual address
  227. ; R2 buffer
  228. ; R3 len
  229. ; CDoPhysical passed private workspace as 5th arg
  230.  
  231.                 IMPORT  CDoPhysical
  232.  
  233. DoPhysical
  234.                 SUB     SP,SP,#1024
  235.                 STR     IP,[SP,#1020]   ;caution, IP=sp
  236.                 ADD     sp,SP,#1020
  237.                 MOV     fp,#0
  238.                 BL      CDoPhysical
  239.                 ADD     SP,SP,#1024
  240.                 LDMFD   SP!,{R0-R3,PC}^
  241.                 ]
  242.  
  243. ; Virtual_TaskInfo
  244. ; Obtains information from the Virtual taskwindow module
  245. ; On entry
  246. ;   R0 = 0 (actually we don't care)
  247. ; On exit
  248. ;   R0 = 0 if not called from inside a virtual taskwindow, else non-zero
  249.  
  250. TaskInfo
  251.                 MOV     R0, #0          ; Always return not from here
  252.                 LDMFD   SP!,{R0-R3,PC}^
  253.          
  254.  
  255. ;R0 cmd string
  256. ;IP currently preferred instantiation
  257.  
  258.                 IMPORT  |__main|
  259.  
  260. start
  261.                 SWI     OS_EnterOS
  262.                 STR     SP,svcstacktop ;record what a flat svcstack is
  263.                 TEQ     PC,#0
  264.                 NOP
  265.                 LDR     ip,[IP]
  266.                 MOV     R6,R0
  267.                 SWI     OS_GetEnv
  268.                 MOV     sp,R1          ;stack at top of memory
  269.                 MOV     R0,#&8000
  270.                 LDR     R2,=&AAAAAAAA
  271.  
  272.                 [       OLD_VERSION
  273.                 TEQ     R0,sp
  274. 00              STRNE   R2,[R0],#4
  275.                 TEQ     R0,sp
  276.                 BNE     %B00
  277.                 |
  278.                 MOV     R3, R2
  279.                 MOV     R4, R2
  280.                 MOV     R5, R2
  281.               ;  TEQ     R0,sp
  282. 00              STMIA   R0!, {R2,R3,R4,R5}
  283.                 CMP     R0,sp
  284.                 BLT     %B00
  285.                 MOV     sp, #&10000    ; stack pointer at 32K to allow
  286.                                        ; increasing wimpslot!
  287.                 ]
  288.  
  289.                 MOV     a2,R6          ;command tail
  290.                 MOV     a1,ip          ;worksp.
  291.                 MOV     fp,#0
  292.                 BL      |__main|
  293.                 SWI     OS_Exit
  294.  
  295. ;**************** Start of Virtual mode interface routines *************
  296.  
  297.  
  298.                 IMPORT  CVSWIV
  299.                 EXPORT  VSWIV
  300.  
  301. VSWIV           TST     lr,#SVC_mode    ;was it user mode?
  302.                 LDRNE   pc,workOldSWIV  ;no, goto old routine
  303.  
  304.                 STR     lr,templr
  305.  
  306.                 LDR     lr,svcstacktop
  307.                 TEQ     lr,SP           ;flat svcstack?
  308.                 LDRNE   lr,templr
  309.                 LDRNE   pc,workOldSWIV  ;no, goto old routine
  310.  
  311.                 MOV     lr,#1
  312.                 STR     lr,worksemaphore
  313.                 TEQP    pc,#SVC_mode    ;Enable ints
  314.                 NOP
  315.                 LDR     lr,workptr     ;point at our workspace
  316.                 STMIA   lr,{R0-lr}^   ;Save all user regs
  317.                 NOP
  318.                 MOV     ip,lr
  319.                 LDR     sp,stacktop
  320.                 LDR     lr,templr
  321.  
  322.                 STR     lr,regs+15*4
  323.                 MOV     a1,ip
  324.                 BIC     a2,lr,#&FC000003
  325.                 LDR     a2,[a2,#-4]
  326.                 MOV     fp,#0
  327.                 ADR     lr,ToCode
  328.                 ORR     lr,lr,#SVC_mode
  329.                 B       CVSWIV        ;must return w again
  330.  
  331.                 EXPORT  VPrefetchAbort
  332.  
  333. VPrefetchAbort
  334.                 STR     lr,templr
  335.                 MOV     lr,#1
  336.                 STR     lr,worksemaphore
  337.                 TEQP    pc,#SVC_mode    ;Enable ints
  338.                 NOP
  339.                 LDR     lr,workptr     ;point at our workspace
  340.                 STMIA   lr,{R0-lr}^   ;Save all user regs
  341.                 NOP
  342.                 MOV     ip,lr
  343.                 LDR     sp,stacktop
  344.                 LDR     lr,templr
  345.  
  346.                 SUB     lr,lr,#4      ;adjust
  347.  
  348.                 BIC     R3,lr,#&FC000003
  349.                 MOV     R4,#4
  350.                 B       VWantAddr
  351.  
  352. ;This is some static workspace, for when we don't have wksp ptr around.
  353. ;Used with care, we are still "reentrant" for use by different Wimp tasks.
  354. ;Set up anew each time we go into virtual mode.
  355. ;Its placed in the middle of the code that wants to use it to stay in
  356. ;addressing range.
  357.  
  358.                 EXPORT  workptr
  359.                 EXPORT  workOldSWIV
  360.                 EXPORT  worksemaphore
  361.                 EXPORT  svcstacktop
  362.  
  363. workptr         &       0               ;Pointer to workspace
  364. workOldSWIV     &       0               ;Place to forward SVC mode swi calls
  365. worksemaphore   &       0
  366. templr          &       0
  367. svcstacktop     &       0
  368.  
  369.                 EXPORT  VDataAbort
  370. VDataAbort
  371.                 STR     lr,templr
  372.                 MOV     lr,#1
  373.                 STR     lr,worksemaphore
  374.                 TEQP    pc,#SVC_mode    ;Enable ints
  375.                 NOP
  376.                 LDR     lr,workptr     ;point at our workspace
  377.                 STMIA   lr,{R0-lr}^   ;Save all user regs
  378.                 NOP
  379.                 MOV     ip,lr
  380.                 LDR     sp,stacktop
  381.                 LDR     lr,templr
  382.                 BIC     R0,lr,#&FC000003
  383.                 STR     R0,regs+15*4    ;For use of pc-relative
  384.  
  385.                 SUB     lr,lr,#8      ;adjust
  386.  
  387.                 BIC     R0,lr,#&FC000003
  388.                 LDR     R1,[R0]                 ;instruction
  389.                 AND     R2,R1,#&f0000           ;base register
  390.                 LDR     R3,[ip,R2,LSR #16-2]   ;get its contents
  391.                 TST     R1,#(1:SHL:26)          
  392.                 BNE     isSTRLDR
  393.                 TST     R1,#(1:SHL:23)          ;direction
  394.                 MOVEQ   R6,#-4
  395.                 MOVNE   R6,#4
  396.                 MOV     R4,#0
  397.                 MOV     R5,R1,LSL#16
  398. 02              MOVS    R5,R5,LSL#1
  399.                 ADDCS   R4,R4,R6
  400.                 BNE     %BT02
  401.                 TST     R1,#(1:SHL:21)          ;writeback ?
  402.                 SUBNE   R3,R3,R4
  403.                 STRNE   R3,[ip,R2,LSR #16-2]
  404.                 B       VWantAddr
  405.  
  406.  
  407. isSTRLDR        TST     R1,#(1:SHL:24)
  408.                 BEQ     %FT01                   ;post index
  409.                 MOV     R4,R1,LSL#32-12         ;12 bits of offset
  410.                 MOV     R4,R4,LSR#32-12
  411.                 TST     R1,#(1:SHL:25)
  412.                 BEQ     %FT02                   ;immed offset
  413.                 AND     R5,R4,#2_1111            ;reg Rm
  414.                 LDR     R5,[ip,R5,LSL#2]
  415.  
  416.                 AND     R6,R4,#2_1100000       ; ALU instruction types, no register specific shift amounts
  417.                                                ; So we have to divide by 2 here to get the 4 instruction
  418.                                                ; offsets 0x00, 0x10, 0x20, 0x30
  419.                 ADD     pc,pc,R6, ASR#1
  420.                 &       0
  421.                 MOV     R6,R4,LSR#7             ;immed shift LSL 0x00
  422.                 MOV     R4,R5,LSL R6
  423.                 B       %FT02
  424.                 &       0
  425.                 MOVS    R6,R4,LSR#7             ;immed shift LSR 0x10
  426.                 ORREQ   R6,R6,#32
  427.                 MOV     R4,R5,LSR R6
  428.                 B       %FT02
  429.                 MOVS    R6,R4,LSR#7             ;immed shift ASR 0x20
  430.                 ORREQ   R6,R6,#32
  431.                 MOV     R4,R5,ASR R6
  432.                 B       %FT02
  433.                 MOVS    R6,R4,LSR#7             ;immed shift ROR 0x30
  434.                 BEQ     itsRRX
  435.                 MOV     R4,R5,ROR R6
  436.                 B       %FT02
  437.  
  438. itsRRX          TEQ     pc,lr,LSL#3            ;get aborted C flag
  439.                 MOV     R4,R5,RRX
  440. 02              TST     R1,#(1:SHL:23)
  441.                 SUBEQ   R3,R3,R4                ;down
  442.                 ADDNE   R3,R3,R4                ;up
  443. 01              MOV     R4,#4
  444.  
  445. ;       R3+R4 = access range, ip = worksp.
  446. ;       resume to R0-R15 on stack
  447.  
  448.                 IMPORT  CVWantAddr
  449.  
  450. VWantAddr
  451.                 STR     lr,regs+15*4            ;now save proper pc
  452.                 [       DEBUG
  453.                 MOV     R0,R3
  454.                 ADR     R1,addr
  455.                 MOV     R2,#8
  456.                 SWI     XOS_ConvertHex8
  457.                 LDR     R0,[ip,#15*4]
  458.                 ADR     R1,addr2
  459.                 MOV     R2,#8
  460.                 SWI     XOS_ConvertHex8
  461.                 ADR     R0,mesg
  462.                 SWI     XOS_Write0
  463.                 ]
  464.                 MOV     a1,ip
  465.                 MOV     a2,R3
  466.                 MOV     a3,R4
  467.                 MOV     fp,#0
  468.                 ADR     lr,ToCode+SVC_mode
  469.                 B       CVWantAddr       ;must return a1 again.
  470.  
  471.                 [       DEBUG
  472. mesg            =       "Abort for addr &"
  473. addr            =       "00000000 at "
  474. addr2           =       "00000000",13,10,0
  475.                 ALIGN
  476.                 ]
  477.  
  478. ;Return to user code, with callback semaphore zeroed.
  479. ;a1 points to workspace
  480.  
  481. ToCode
  482.                 MOV     lr,pc
  483.                 TST     lr,#3
  484.                 ADREQ   R0,ToCodeErr
  485.                 SWIEQ   OS_GenerateError
  486.  
  487.                 TEQP    pc,#SVC_mode+I_bit      ;disable ints
  488.                 NOP
  489.  
  490.                 LDR     lr,worksemaphore
  491.                 SUBS    lr,lr,#1
  492.                 BNE     VCallBack1
  493.                 STR     lr,worksemaphore
  494.  
  495.                 MOV     lr,a1          ;reg block to a SVC reg
  496.                 LDMIA   lr,{R0-lr}^   ;load user regs
  497.                 NOP
  498.                 LDR     lr,[lr,#15*4] ;user pc
  499.                 MOVS    pc,lr          ;into user mode and go!
  500.  
  501. ToCodeErr       &       0
  502.                 =       "Life is bad in ToCode",0
  503.                 ALIGN
  504.  
  505.                 IMPORT  CVCallBack
  506.                 EXPORT  VCallBack
  507. VCallBack
  508.                 MOV     a1,IP
  509.                 MOV     ip,a1
  510.                 LDR     sp,stacktop
  511.                 MOV     lr,#1
  512. VCallBack1
  513.                 STR     lr,worksemaphore
  514.                 TEQP    pc,#SVC_mode    ;enable ints
  515.                 NOP
  516.                 MOV     fp,#0
  517.                 ADR     lr,ToCode+SVC_mode
  518.                 B       CVCallBack       ;must return a1 again.
  519.  
  520. ;Regular Ticker CallEvery Centi-second
  521.  
  522.                 EXPORT  OurCallEvery
  523. OurCallEvery    LDR     IP,worksemaphore
  524.                 TEQ     IP,#0
  525.                 ADDNE   IP,IP,#1
  526.                 STRNE   IP,worksemaphore
  527.                 MOVNES  pc,lr
  528.                 STMFD   SP!,{lr}
  529.                 MOV     IP,pc
  530.                 TEQP    pc,#I_bit+SVC_mode
  531.                 NOP
  532.                 STMFD   SP!,{lr}
  533.                 SWI     XOS_SetCallBack
  534.                 LDMFD   SP!,{lr}
  535.                 TEQP    IP,#0
  536.                 NOP
  537.                 LDMFD   SP!,{pc}^
  538.  
  539. ; Convert various sorts of events to C
  540.  
  541.                 IMPORT  CVUpCall
  542.                 EXPORT  VUpCall
  543. VUpCall         STMFD   SP!,{R1-IP,LR}
  544.                 MOV     a4,IP
  545.                 MOV     sp,SP
  546.                 SUB     SP,SP,#1024
  547.                 MOV     fp,#0
  548.                 BL      CVUpCall
  549.                 ADD     SP,SP,#1024
  550.                 LDMFD   SP!,{R1-IP,PC}^
  551.  
  552.                 EXPORT  VError
  553. VError          SWI     OS_GenerateError
  554.  
  555.                 EXPORT  VExit
  556. VExit           SWI     OS_Exit         ;call in user mode to caught by VSWIV
  557.  
  558. ; Convert various sorts of events to C
  559.  
  560.                 IMPORT  CExtUpCall
  561.                 EXPORT  ExtUpCall
  562. ExtUpCall       STMFD   SP!,{R1-IP,LR}
  563.                 MOV     a4,IP
  564.                 MOV     sp,SP
  565.                 SUB     SP,SP,#1024
  566.                 MOV     fp,#0
  567.                 BL      CExtUpCall
  568.                 ADD     SP,SP,#1024
  569.                 LDMFD   SP!,{R1-IP,PC}^
  570.  
  571.                 IMPORT  CExtError
  572.                 EXPORT  ExtError
  573. ExtError        MOV     ip,R0
  574.                 LDR     sp,stacktop
  575.                 MOV     fp,#0
  576.                 BL      CExtError
  577.                 SWI     OS_GenerateError
  578.  
  579.                 IMPORT  CExtExit
  580.                 EXPORT  ExtExit
  581. ExtExit
  582.                 MOV     a1,IP
  583.                 MOV     ip,a1
  584.                 LDR     sp,stacktop
  585.                 MOV     fp,#0
  586.                 BL      CExtExit
  587.                 SWI     OS_Exit
  588.  
  589.                 IMPORT  CExtWriteC
  590. K               *       &80000001
  591. ;return K to pass vector on with input flag values
  592. ;return K-1 for VC CC
  593. ;return K+1 for VC CS
  594. ;return K-2 for VS CC
  595.  
  596.                 EXPORT  ExtWriteC
  597. ExtWriteC
  598.                 STMFD   SP!,{R0-IP,LR}
  599.                 SUB     SP,SP,#8
  600.                 STMIA   SP,{SP,LR}^
  601.                 NOP
  602.                 MOV     a2,IP
  603.                 MOV     sp,SP
  604.                 SUB     SP,SP,#1024
  605.                 MOV     fp,#0
  606.                 BL      CExtWriteC
  607.                 ADD     SP,SP,#1024
  608.                 LDMIA   SP,{SP,LR}^
  609.                 NOP
  610.                 ADD     SP,SP,#8
  611.                 CMP     R0,#K
  612.                 LDMEQFD SP!,{R0-IP,PC}^
  613.                 LDMFD   SP!,{R0-IP,LR,PC}
  614.  
  615. ; Convert various sorts of events to C
  616.  
  617.                 IMPORT  CNormWriteC
  618. ;return K to pass vector on with input flag values
  619. ;return K-1 for VC CC
  620. ;return K+1 for VC CS
  621. ;return K-2 for VS CC
  622.  
  623.                 EXPORT  NormWriteC
  624. NormWriteC
  625.                 STMFD   SP!,{R0-IP,LR}
  626.                 SUB     SP,SP,#8
  627.                 STMIA   SP,{SP,LR}^
  628.                 NOP
  629.                 MOV     a2,IP
  630.                 MOV     sp,SP
  631.                 SUB     SP,SP,#1024
  632.                 MOV     fp,#0
  633.                 BL      CNormWriteC
  634.                 ADD     SP,SP,#1024
  635.                 LDMIA   SP,{SP,LR}^
  636.                 NOP
  637.                 ADD     SP,SP,#8
  638.                 CMP     R0,#K
  639.                 LDMEQFD SP!,{R0-IP,PC}^
  640.                 LDMFD   SP!,{R0-IP,LR,PC}
  641.  
  642.                 IMPORT  CNormUpCall
  643.                 EXPORT  NormUpCall
  644. NormUpCall      STMFD   SP!,{R1-IP,LR}
  645.                 MOV     a4,IP
  646.                 MOV     sp,SP
  647.                 SUB     SP,SP,#1024
  648.                 MOV     fp,#0
  649.                 BL      CNormUpCall
  650.                 ADD     SP,SP,#1024
  651.                 LDMFD   SP!,{R1-IP,PC}^
  652.  
  653.                 IMPORT  CNormError
  654.                 EXPORT  NormError
  655. NormError       MOV     ip,R0
  656.                 LDR     sp,stacktop
  657.                 MOV     fp,#0
  658.                 BL      CNormError
  659.                 SWI     OS_GenerateError
  660.  
  661.                 IMPORT  CNormExit
  662.                 EXPORT  NormExit
  663. NormExit
  664.                 MOV     a1,IP
  665.                 MOV     ip,a1
  666.                 LDR     sp,stacktop
  667.                 MOV     fp,#0
  668.                 BL      CNormExit
  669.                 SWI     OS_Exit
  670.  
  671. ; Mode changing
  672. ; Now we use R12 as stack, less messy, and idempotent
  673.  
  674.                 EXPORT  usermode
  675. usermode        MOV     a2,lr
  676.                 TEQP    pc,#USR_mode
  677.                 NOP
  678.                 MOV     pc,a2
  679.  
  680.                 EXPORT  svcmode
  681. svcmode         MOV     a2,lr
  682.                 SWI     XOS_EnterOS
  683.                 MOV     pc,a2
  684.  
  685.                 EXPORT  CallEscapeHandler
  686. CallEscapeHandler
  687.                 MOV     ip, sp
  688.                 STMFD   sp!, {v1, v2, fp, ip, lr, pc}
  689.                 SUB     fp, ip, #4
  690.                 MOV     v1, fp          ; save fp and SP
  691.                 MOV     v2, SP
  692.                 MOV     SP, sp          ; pass our stack on
  693.                 MOV     ip, a3          ; R11 escape condition
  694.                 MOV     sp, a2          ; R12
  695.                 MOV     lr, pc
  696.                 MOV     pc, a1          ; call user escape handler
  697.                 MOV     a1, sp          ; R12 is return call back flag
  698.                 MOV     SP, v2          ; restore fp and SP
  699.                 MOV     fp, v1
  700.                 LDMEA   fp, {v1, v2, fp, sp, pc}^
  701.                 
  702.                 END
  703.